package com.example;


import java.util.Comparator;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.ConcurrentSkipListMap;
import java.util.stream.Collectors;

import static com.example.CollectorsAction.menu;

/**
 * @author Liuqz
 * @date 2018/11/18 19:15
 */
public class CollectorsAction2 {

    public static void main(String[] args) {
        testGroupingByConcurrentWithFunction();
        testGroupingByConcurrentWithFunctionAndCollector();
        testGroupingByConcurrentWithFunctionAndSupplierAndCollector();
        testJoining();
        testJoiningWithDelimiter();
        testJoiningWithDelimiterAndPrefixAndSuffix();
        testMapping();
        testmaxBy();
        testMinBy();
    }

    //根据Dish.Type分类并返回一个ConcurrentMap<Dish.Type, List<Dish>> map
    private static void testGroupingByConcurrentWithFunction() {
        System.out.println("testGroupingByConcurrentWithFunction");

        ConcurrentMap<Dish.Type, List<Dish>> collect = menu.stream().collect(Collectors.groupingByConcurrent(Dish::getType));
        Optional.ofNullable(collect.getClass()).ifPresent(System.out::println);
        Optional.ofNullable(collect).ifPresent(System.out::println);
    }

    //根据Dish.Type分类并计算出每个Type的平均值
    private static void testGroupingByConcurrentWithFunctionAndCollector() {
        System.out.println("testGroupingByConcurrentWithFunctionAndCollector");

        ConcurrentMap<Dish.Type, Double> collect = menu.stream().collect(Collectors.groupingByConcurrent(Dish::getType, Collectors.averagingInt(Dish::getCalories)));
        Optional.ofNullable(collect).ifPresent(System.out::println);
    }

    //根据Dish.Type分类并计算出每个Type的平均值 返回ConcurrentSkipListMap
    private static void testGroupingByConcurrentWithFunctionAndSupplierAndCollector() {
        System.out.println("testGroupingByConcurrentWithFunctionAndSupplierAndCollector");

        ConcurrentMap<Dish.Type, Double> collect = menu.stream().collect(Collectors.groupingByConcurrent(Dish::getType, ConcurrentSkipListMap::new,Collectors.averagingInt(Dish::getCalories)));
        Optional.ofNullable(collect).ifPresent(System.out::println);
    }

    /**
     * 将Dish.Name全部输出没有间隙
     * result : porkbeefchickenfrench friesriceseason fruitpizzaprawnssalmon
     */
    private static void testJoining() {
        System.out.println("testJoining");
        Optional.ofNullable(menu.stream().map(Dish::getName).collect(Collectors.joining())).ifPresent(System.out::println);
    }

    /**
     * 将Dish.Name全部输入并且每个Name按, 分割
     * result : pork,beef,chicken,french fries,rice,season fruit,pizza,prawns,salmon
     */
    private static void testJoiningWithDelimiter() {
        System.out.println("testJoiningWithDelimiter");
        Optional.ofNullable(menu.stream().map(Dish::getName).collect(Collectors.joining(","))).ifPresent(System.out::println);
    }

    //result : Name:[pork,beef,chicken,french fries,rice,season fruit,pizza,prawns,salmon]
    private static void testJoiningWithDelimiterAndPrefixAndSuffix() {
        System.out.println("testJoiningWithDelimiterAndPrefixAndSuffix");
        Optional.ofNullable(menu.stream().map(Dish::getName).collect(Collectors.joining(",","Name:[","]"))).ifPresent(System.out::println);
    }

    /**
     * 获取Dish.Name并使用 ,  分割
     * result : pork,beef,chicken,french fries,rice,season fruit,pizza,prawns,salmon
     */
    private static void testMapping() {
        System.out.println("testMapping");
        Optional.ofNullable(menu.stream().collect(Collectors.mapping(Dish::getName, Collectors.joining(",")))).ifPresent(System.out::println);
    }

    /**
     * 根据Dish.Calories获取最大的Dish
     * result : Optional[Dish(name=pork, vegetarian=false, calories=800, type=MEAT)]
     */
    private static void testmaxBy() {
        System.out.println("testmaxBy");
        Optional.ofNullable(menu.stream().collect(Collectors.maxBy(Comparator.comparing(Dish::getCalories)))).ifPresent(System.out::println);
    }

    /**
     * 根据Dish.Calories获取最小的Dish
     * result : Optional[Dish(name=season fruit, vegetarian=true, calories=120, type=OTHER)]
     */
    private static void testMinBy() {
        System.out.println("testMinBy");
        Optional.ofNullable(menu.stream().collect(Collectors.minBy(Comparator.comparing(Dish::getCalories)))).ifPresent(System.out::println);
    }
}
